package c.m.d.b.rest;


import c.m.d.b.assembler.EntityTypeAssembler;
import c.m.d.b.beans.EntityInstance;
import c.m.d.b.beans.EntityType;
import c.m.d.b.beans.PropertyValue;
import c.m.d.b.exception.CMDBException;
import c.m.d.b.rest.beans.IdList;
import c.m.d.b.service.EntityInstanceService;
import c.m.d.b.service.EntityTypeService;
import c.m.d.b.util.Utils;
import c.m.d.b.view.EntityTypeView;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Path("/v1")
@Produces(MediaType.APPLICATION_JSON)
@Component
public final class EntityResource
{
    //TODO enable dependency injection using the jee annotation
    //spring supports those
    @Autowired
    private EntityInstanceService entityInstanceService;

    @Autowired
    private EntityTypeService entityTypeService;


    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Path("/{typename}/instance")
    public String createEntityInstance(@PathParam("typename") String entityTypeName,
            final EntityInstance entityInstance)
    {
        if (!Utils.nullCompareString(entityTypeName, entityInstance.getTypeName()))
        {
            throw new CMDBException(CMDBException.CMDBErrorCode.BAD_REQUEST, "Type names do not match");
        }
        return entityInstanceService.createEntityInstance(entityInstance);
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Path("/{typename}/instance/{id}")
    public void updateEntityInstance(@PathParam("typename") String entityTypeName,
            @PathParam("id") String entityInstnaceId, EntityInstance entityInstance)
    {
        if (!Utils.nullCompareString(entityTypeName, entityInstance.getTypeName()))
        {
            throw new CMDBException(CMDBException.CMDBErrorCode.BAD_REQUEST, "Type names do not match");
        }
        if (!Utils.nullCompareString(entityInstnaceId, entityInstance.getId()))
        {
            throw new CMDBException(CMDBException.CMDBErrorCode.BAD_REQUEST, "Ids do not match");
        }
        entityInstanceService.updateEntityInstance(entityInstance);

    }

    @DELETE
    @Path("/{typename}/instance/{id}")
    public void deleteEntityInstance(@PathParam("typename") String typeName, @PathParam("id") String entityInstanceId)
    {
        //TODO typeName is not being used
        entityInstanceService.deleteEntityInstance(entityInstanceId);
    }

    @GET
    @Path("/{typename}/instance/{id}")
    public EntityInstance getEntityInstance(@PathParam("typename") String entityType,
            @PathParam("id") String entityInstanceId)
    {
        return entityInstanceService.getEntityInstance(entityType, entityInstanceId);
    }

    @GET
    @Path("/{typename}/instance")
    public List<EntityInstance> getEntityInstances(@PathParam("typename") String entityType)
    {
        return entityInstanceService.getEntityInstances(entityType);
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Path("/{typename}/instance/{id}/properties")
    public void updateEntityInstanceProperties(@PathParam("typename") String entityTypeName,
            @PathParam("id") String entityInstanceId,
            Set<PropertyValue> propertyInstances)
    {
        entityInstanceService.updateEntityInstanceProperties(entityTypeName, entityInstanceId, propertyInstances);
    }

    @POST
    @Path("/{typename}/instance/{id}/properties/{idlist}")
    public void deleteEntityInstanceProperties(@PathParam("typename") String entityTypeName,
            @PathParam("id") String entityInstanceId, @PathParam("idlist") IdList idList)
    {
        entityInstanceService.deleteEntityInstanceProperties(entityTypeName, entityInstanceId,
                new HashSet<String>(idList.asCollection()));
    }

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Path("/{typename}")
    public String createEntityType(@PathParam("typename") String entityTypeName, EntityType entityType)
    {
        if (!Utils.nullCompareString(entityTypeName, entityType.getEntityTypeName()))
        {
            throw new CMDBException(CMDBException.CMDBErrorCode.BAD_REQUEST, "Type names do not match");
        }
        return entityTypeService.createEntityType(entityType);
    }

    @GET
    @Path("/{typename}")
    public EntityTypeView getEntityType(@PathParam("typename") String entityTypeName)
    {
        return EntityTypeAssembler.convert(entityTypeService.getEntityType(entityTypeName));
    }

    @GET
    public List<String> getEntityTypesNames()
    {
        return entityTypeService.getEntityTypesNames();
    }


}
